/*
 * $Id: PDFAnnot.java,v 1.3 2001/11/16 15:26:04 ezb Exp $
 *
 * $Date: 2001/11/16 15:26:04 $
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public 
 * License as published by the Free Software Foundation; either 
 * version 2.1 of the License, or (at your option) any later version. 
 * 
 * This library is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
 * Lesser General Public License for more details. 
 * 
 * You should have received a copy of the GNU Lesser General Public 
 * License along with this library; if not, write to the Free Software 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */
package gnu.jpdf;

import java.io.*;

/**
 * <p>This class defines an annotation (commonly known as a Bookmark).</p>
 *
 * @author Eric Z. Beard, ericzbeard@hotmail.com
 * @author Peter T Mount, http://www.retep.org.uk/pdf/
 * @author $Author: ezb $
 * @version $Revision: 1.3 $, $Date: 2001/11/16 15:26:04 $
 */
public class PDFAnnot extends PDFObject implements Serializable
{
	private static final long serialVersionUID = 1L;

	/*
	 * NOTE: The original class is the work of Peter T. Mount, who released it 
	 * in the uk.org.retep.pdf package.  It was modified by Eric Z. Beard as 
	 * follows: the package name was changed to gnu.pdf.  It is still 
	 * licensed under the LGPL.
	 */

	/**
	 * Solid border. The border is drawn as a solid line.
	 */
	public static final short SOLID = 0;

	/**
	 * The border is drawn with a dashed line.
	 */
	public static final short DASHED = 1;

	/**
	 * The border is drawn in a beveled style (faux three-dimensional) such
	 * that it looks as if it is pushed out of the page (opposite of INSET)
	 */
	public static final short BEVELED = 2;

	/**
	 * The border is drawn in an inset style (faux three-dimensional) such
	 * that it looks as if it is inset into the page (opposite of BEVELED)
	 */
	public static final short INSET = 3;

	/**
	 * The border is drawn as a line on the bottom of the annotation rectangle
	 */
	public static final short UNDERLINED = 4;

	/**
	 * The subtype of the outline, ie text, note, etc
	 */
	private String subtype;

	/**
	 * The size of the annotation
	 */
	private int l,b,r,t;

	/**
	 * The text of a text annotation
	 */
	private String s;

	/**
	 * flag used to indicate that the destination should fit the screen
	 */
	private static final int FULL_PAGE = -9999;

	/**
	 * Link to the Destination page 
	 */
	private PDFObject dest;

	/**
	 * If fl!=FULL_PAGE then this is the region of the destination page shown.
	 * Otherwise they are ignored.
	 */
	private int fl,fb,fr,ft;

	/**
	 * the border for this annotation
	 */
	private PDFBorder border;

	/**
	 * This is used to create an annotation.
	 * @param s Subtype for this annotation
	 * @param l Left coordinate
	 * @param b Bottom coordinate
	 * @param r Right coordinate
	 * @param t Top coordinate
	 */
	protected PDFAnnot(String s,int l,int b,int r,int t)
	{
		super("/Annot");
		subtype = s;
		this.l = l;
		this.b = b;
		this.r = r;
		this.t = t;
	}

	/**
	 * Creates a text annotation
	 * @param l Left coordinate
	 * @param b Bottom coordinate
	 * @param r Right coordinate
	 * @param t Top coordinate
	 * @param s Text for this annotation
	 */
	public PDFAnnot(int l,int b,int r,int t,String s) 
	{
		this("/Text",l,b,r,t);
		this.s = s;
	}

	/**
	 * Creates a link annotation
	 * @param l Left coordinate
	 * @param b Bottom coordinate
	 * @param r Right coordinate
	 * @param t Top coordinate
	 * @param dest Destination for this link. The page will fit the display.
	 */
	public PDFAnnot(int l,int b,int r,int t,PDFObject dest) 
	{
		this("/Link",l,b,r,t);
		this.dest = dest;
		this.fl = FULL_PAGE; // this is used to indicate a full page
	}

	/**
	 * Creates a link annotation
	 * @param l Left coordinate
	 * @param b Bottom coordinate
	 * @param r Right coordinate
	 * @param t Top coordinate
	 * @param dest Destination for this link
	 * @param rect Rectangle describing what part of the page to be displayed
	 * (must be in User Coordinates)
	 */
	public PDFAnnot(int l,int b,int r,int t,PDFObject dest,int fl,int fb,int fr,int ft) 
	{
		this("/Link",l,b,r,t);
		this.dest = dest;
		this.fl = fl;
		this.fb = fb;
		this.fr = fr;
		this.ft = ft;
	}

	/**
	 * Sets the border for the annotation. By default, no border is defined.
	 *
	 * <p>If the style is DASHED, then this method uses PDF's default dash
	 * scheme {3}
	 *
	 * <p>Important: the annotation must have been added to the document before
	 * this is used. If the annotation was created using the methods in
	 * PDFPage, then the annotation is already in the document.
	 *
	 * @param style Border style SOLID, DASHED, BEVELED, INSET or UNDERLINED.
	 * @param width Width of the border
	 */
	public void setBorder(short style,double width)
	{
		border = new PDFBorder(style,width);
		pdfDocument.add(border);
	}

	/**
	 * Sets the border for the annotation. Unlike the other method, this
	 * produces a dashed border.
	 *
	 * <p>Important: the annotation must have been added to the document before
	 * this is used. If the annotation was created using the methods in
	 * PDFPage, then the annotation is already in the document.
	 *
	 * @param width Width of the border
	 * @param dash Array of lengths, used for drawing the dashes. If this
	 * is null, then the default of {3} is used.
	 */
	public void setBorder(double width,double dash[]) 
	{
		border = new PDFBorder(width,dash);
		pdfDocument.add(border);
	}

	/**
	 * Should this be public??
	 *
	 * @param os OutputStream to send the object to
	 * @exception IOException on error
	 */
	public void write(OutputStream os) throws IOException 
	{
		// Write the object header
		writeStart(os);

		// now the objects body
		os.write("/Subtype ".getBytes());
		os.write(subtype.getBytes());
		os.write("\n/Rect [".getBytes());
		os.write(Integer.toString(l).getBytes());
		os.write(" ".getBytes());
		os.write(Integer.toString(b).getBytes());
		os.write(" ".getBytes());
		os.write(Integer.toString(r).getBytes());
		os.write(" ".getBytes());
		os.write(Integer.toString(t).getBytes());
		os.write("]\n".getBytes());

		// handle the border
		if(border==null) 
		{
			os.write("/Border [0 0 0]\n".getBytes());
			//if(pdf.defaultOutlineBorder==null)
			//pdf.add(pdf.defaultOutlineBorder = new border(SOLID,0.0));
			//os.write(pdf.defaultOutlineBorder.toString().getBytes());
		} 
		else 
		{
			os.write("/BS ".getBytes());
			os.write(border.toString().getBytes());
			os.write("\n".getBytes());
		}

		// Now the annotation subtypes
		if(subtype.equals("/Text")) 
		{
			os.write("/Contents ".getBytes());
			os.write(PDFStringHelper.makePDFString(s).getBytes());
			os.write("\n".getBytes());
		} 
		else if(subtype.equals("/Link")) 
		{
			os.write("/Dest [".getBytes());
			os.write(dest.toString().getBytes());
			if(fl==FULL_PAGE)
				os.write(" /Fit]".getBytes());
			else 
			{
				os.write(" /FitR ".getBytes());
				os.write(Integer.toString(fl).getBytes());
				os.write(" ".getBytes());
				os.write(Integer.toString(fb).getBytes());
				os.write(" ".getBytes());
				os.write(Integer.toString(fr).getBytes());
				os.write(" ".getBytes());
				os.write(Integer.toString(ft).getBytes());
				os.write("]".getBytes());
			}
			os.write("\n".getBytes());
		}

		// finish off with its footer
		writeEnd(os);
	}
}